package com.github.sbb.sherry.console.service.engine.config;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.sbb.sherry.common.base.Preconditions;
import com.github.sbb.sherry.common.base.ValidateResult;
import com.github.sbb.sherry.common.primitives.StringUtil;
import com.github.sbb.sherry.console.dto.PageList;
import com.github.sbb.sherry.console.exception.LogicException;
import com.github.sbb.sherry.primitives.config.fetcher.FetcherConfig;
import com.github.sbb.sherry.primitives.config.fetcher.HttpFetcherConfig;
import com.github.sbb.sherry.primitives.config.fetcher.MongoDBFetcherConfig;
import com.github.sbb.sherry.primitives.config.fetcher.MySQLFetcherConfig;
import com.github.sbb.sherry.repository.FetcherRepository;
import com.github.sbb.sherry.repository.entity.Fetcher;
import com.github.sbb.sherry.repository.enums.DatasourceStatusEnum;
import com.github.sbb.sherry.repository.enums.DeleteFlagEnum;
import com.github.sbb.sherry.repository.enums.FetcherTypeEnum;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
@Service
public class FetcherConfigService {

  @Autowired
  private FetcherRepository fetcherRepository;

  public void addFetcher(Fetcher param) {
    Byte type = param.getType();
    ValidateResult validateResult = validateFetcherConfig(type, param.getExpansionConfig());

    if (validateResult.isFailure()) {
      throw new LogicException(validateResult.getMessage());
    }

    String fetcherName = param.getName().trim();
    long count = fetcherRepository.countByName(fetcherName);
    Preconditions.checkArgument(count == 0, "已经有同名 datasource 无法添加");

    Fetcher fetcher = new Fetcher();
    fetcher.setName(fetcherName);
    fetcher.setType(type);
    fetcher.setDescription(param.getDescription());
    fetcher.setDeleteFlag(DeleteFlagEnum.NOT_DELETED.getValue());
    fetcher.setStatus(DatasourceStatusEnum.ACTIVE.getValue());
    fetcher.setExpansionConfig(param.getExpansionConfig());
    fetcher.setEstimatedExecutionTime(param.getEstimatedExecutionTime());
    fetcher.setDefaultFetchMethod(param.getDefaultFetchMethod());
    fetcher.setDatasource(param.getDatasource());

    fetcherRepository.addFetcher(fetcher);
  }

  private ValidateResult validateFetcherConfig(byte type, String expansionConfig) {
    FetcherConfig fetcherConfig = null;
    // TODO 如果写成 MAP 就不用这样判断了，先凑合吧
    if (type == FetcherTypeEnum.HTTP.getValue()) {
      fetcherConfig = JSON.parseObject(expansionConfig, HttpFetcherConfig.class);
    } else if (type == FetcherTypeEnum.MYSQL.getValue()) {
      fetcherConfig = JSON.parseObject(expansionConfig, MySQLFetcherConfig.class);
    } else if (type == FetcherTypeEnum.REDIS.getValue()) {
    } else if (type == FetcherTypeEnum.MONGODB.getValue()) {
      fetcherConfig = JSON.parseObject(expansionConfig, MongoDBFetcherConfig.class);
    }
    if (fetcherConfig != null) {
      return fetcherConfig.validate();
    }
    return new ValidateResult(false, StringUtil.lenientFormat("没找到能和 Type: {} 想匹配的DataSourceConfig，请检查相关代码或者配置", type));
  }

  public PageList<Fetcher> pageList(int currentPage, Integer pageSize) {
    if (pageSize == null) {
      pageSize = 10;
    }

    Page<Object> page = PageHelper.startPage(currentPage, pageSize);

    List<Fetcher> activeFetcher = fetcherRepository.getActiveFetchers();

    return new PageList(currentPage, pageSize, page.getTotal(), activeFetcher);
  }
}
